﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
namespace HB.WpfEx
{
    public class ImageStreamRotate
    {
        public enum RotateTypes
        {
            Clockwise90, Clockwise180, Clockwise270
        }
        int[] ConvertMap;
        /// <summary>
        /// 原始尺寸，当前x,当前y，转化后的xy对应的索引
        /// </summary>
        static Func<Size, int, int, int> Clockwise90 = (sourceSize, x, y) =>
        {//x=h-y0 //y=x0
            var xn = sourceSize.Height - 1 - y;
            var yn = x;
            var widthn = sourceSize.Height;
            return yn * widthn + xn;
        };
        static Func<Size, int, int, int> Clockwise180 = (sourceSize, x, y) =>
        {//x=w-x0 //y=h-y0
            var xn = sourceSize.Width - 1 - x;
            var yn = sourceSize.Height - 1 - y;
            var widthn = sourceSize.Width;
            return yn * widthn + xn;
        };
        static Func<Size, int, int, int> Clockwise270 = (sourceSize, x, y) =>
        {
            //x=y0 //y=w-x0
            var xn = y;
            var yn = sourceSize.Width - 1 - x;
            var widthn = sourceSize.Height;
            return yn * widthn + xn;
        };
        Dictionary<RotateTypes, Func<Size, int, int, int>> dic = new Dictionary<RotateTypes, Func<Size, int, int, int>>()
        {
            { RotateTypes.Clockwise90 ,Clockwise90 },
            { RotateTypes.Clockwise180 ,Clockwise180 },
            { RotateTypes.Clockwise270 ,Clockwise270 },
        };
        public ImageStreamRotate(Size sourceSize, RotateTypes RotateFlip)
        {
            ConvertMap = new int[sourceSize.Width * sourceSize.Height];
            var f = dic[RotateFlip];
            int sourceindex = 0;
            for (int y = 0; y < sourceSize.Height; y++)
            {
                for (int x = 0; x < sourceSize.Width; x++)
                {
                    sourceindex = y * sourceSize.Width + x;
                    var targetindex = f(sourceSize, x, y);
                    ConvertMap[sourceindex] = targetindex;                   
                }
            }
        }
        public T[] Rotate<T>(T[] source)
        {
            T[] result = new T[ConvertMap.Length];
            for (int i = 0; i < ConvertMap.Length; i++)
            {
                result[ConvertMap[i]] = source[i];
            }
            return result;
        }
        public void Rotate<T>(T[] source, T[] target)
        {

            for (int i = 0; i < ConvertMap.Length; i++)
            {
                target[ConvertMap[i]] = source[i];
            }
        }
    }
}
